/*jslint vars: true, forin: true, sloppy: true */
/*global angular, ocDialog, DialogManager, DialogFactory */
ocDialog.directive("ocGrid", function ($filter) {
	var getMaxDataWidth = function (data) {
		var maxLength = 0;
		angular.forEach(data, function (row) {
			if (row.length > maxLength) {
				maxLength = row.length;
			}
		});

		return maxLength;
	};

	return {
		restrict: 'E',
		replace: true,
		controller: angular.noop,
		scope: {
			data: '=ocGridData',
			control: '=?ocGridControl',
			refresh: '=?ocGridRefresh'
		},
		template:
			'<div class="oc-grid"><section class="oc-grid-bisect">Excel</section>' +

				// 横向行表头
				'<section class="oc-grid-row-header" style="left:0;">' +
				'<div ng-repeat="t in control.header track by $index" ng-style="{width:t.width+\'px\'}"' +
				'ng-class="{selected:control.$position.col==$index}">{{t.text}}' +
				'<hr ng-mousedown="resize($event, $index)" /></div></section>' +

				// 纵向列表头
				'<section class="oc-grid-col-header" style="top:0;">' +
				'<div style="height:30px" ng-repeat="row in data track by $index"' +
				'ng-class="{selected:control.$position.row==$index}">{{$index}}</div></section>' +

				// 数据滚动区
				'<div class="oc-grid-inner"><table>' +

					// 数据行表头宽度控制
					'<thead><tr><th ng-repeat="t in control.header track by $index">' +
					'<div  ng-style="{width:t.width+\'px\'}"></div></th></tr></thead>' +

					// 数据渲染区
					'<tbody><tr ng-repeat="rowData in gridData track by $index" style="height:30px;">' +
					'<td ng-repeat="cellData in rowData track by $index" ' +
					'ng-class="{selected:control.$position.row==$parent.$index && control.$position.col==$index}" ' +
					'ng-click="selectCell($parent.$index, $index, $event)" ng-dblclick="editCell($event)">' +
					'<div>{{cellData}}</div></td></tr></tbody>' +
					'</table><textarea ng-model="data[control.$position.row][control.$position.col]" ' +
					'ng-blur="cancelEditMode()"' +
					'ng-show="isEditable" class="oc-grid-input" ' +
					'ng-style="input">' +
				'</textarea></div></div>',
		link: function (scope, element, attr) {
			var maxDataWidth = getMaxDataWidth(scope.data);
			scope.control = scope.control || {};
			scope.control.header = scope.control.header || $filter('gridAutoHeader')(maxDataWidth, 120);
			scope.control.$position = { col: 0, row: 0 };

			scope.$watchGroup(['data', 'data.length', 'refresh', function (scope) {
				// 如果control没定义header返回false，定义了则返回header的长度
				return scope.control.header && scope.control.header.length;
			}], function () {
				// Get a gridMatrix to view.
				scope.gridData = $filter('gridMatrix')(scope.data, scope.control.header.length);

				// 整理标题
				if (!scope.control.header || !scope.control.header.length) {
					maxDataWidth = getMaxDataWidth(scope.data);
					scope.control.header = $filter('gridAutoHeader')(maxDataWidth, 120);
				}
			});

			// 调整宽度 TODO 复用 ocCore的代码
			var initLeft, initWidth, resizeHandleIndex, minWidth = 10,
				resizing = function (event) {
					scope.$apply(function () {
						scope.control.header[resizeHandleIndex].width =
							Math.max(initWidth + event.clientX - initLeft, minWidth);
					});
				},
				cancelResizable = function () {
					element.off("mousemove", resizing);
					element.off("mouseup", cancelResizable);
				};

			scope.resize = function (event, index) {
				initLeft = event.clientX;
				initWidth = scope.control.header[index].width;
				resizeHandleIndex = index;

				element.on("mousemove", resizing).on("mouseup", cancelResizable);
			};

			// 选择单元格
			scope.selectCell = function (row, col, event) {
				var pos = scope.control.$position;
				pos.row = row;
				pos.col = col;
				(scope.control.selectFn || angular.noop).call(scope.data, row, col, event);
			};

			scope.cancelEditMode = function () {
				scope.isEditable = false;
				scope.gridData = $filter('gridMatrix')(scope.data, scope.control.header.length);
			};

			// 编辑单元格
			scope.isEditable = false;
			scope.input = { top: 0, left: 0, width: 0, height: 0 };
			scope.editCell = function (event) {
				scope.isEditable = true;
				var $ = event.target.offsetParent;

				scope.input = { top: $.offsetTop + 'px', left: $.offsetLeft + 'px',
					// 需要减去边框的1像素影响
					width: $.offsetWidth - 1 + 'px', height: $.offsetHeight - 1 + 'px' };

				// Focus the input
				setTimeout(function () {
					scope.inputBox[0].focus();
				}, 0);
			};
		}
	};
}).directive("ocGridInner", function ($filter) {
	return {
		restrict: "C",
		require: '^ocGrid',
		link: function (scope, element) {
			element.on('scroll', $filter('throttle')(function () {
				scope.rowHeader[0].style.left = '-' + element[0].scrollLeft + 'px';
				scope.colHeader[0].style.top = '-' + element[0].scrollTop + 'px';
			}, 0));
		}
	};
}).directive("ocGridRowHeader", function () {
	return {
		restrict: "C",
		require: '^ocGrid',
		link: function (scope, element) {
			scope.rowHeader = element;
		}
	};
}).directive("ocGridInput", function () {
	return {
		restrict: "C",
		require: '^ocGrid',
		link: function (scope, element) {
			scope.inputBox = element;
		}
	};
}).directive("ocGridColHeader", function () {
	return {
		restrict: "C",
		require: '^ocGrid',
		link: function (scope, element) {
			scope.colHeader = element;
		}
	};
});

